﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Codeflows.Results;

namespace Codeflows
{
    public abstract class Codeflow
    {
        protected Result Jump<T>(Expression<Func<T, Result>> action) where T : Codeflow
        {
            var result = CreateNavigationResult(action);
            return new JumpResult(result.ActionName, result.Arguments);
        }

        protected Result Jump<T>(Expression<Func<T, Task<Result>>> action) where T : Codeflow
        {
            var result = CreateNavigationResult(action);
            return new JumpResult(result.ActionName, result.Arguments);
        }

        protected Result DelayedJump<T>(Expression<Func<T, Result>> action, TimeSpan delay) where T : Codeflow
        {
            var result = CreateNavigationResult(action);
            return new DelayedJumpResult(result.ActionName, result.Arguments, delay);
        }


        protected Result End()
        {
            return new EndResult();
        }

        protected Result End(object value)
        {
            return new EndResult(value);
        }

        protected Result Pause(string resumeAction)
        {
            return new PausedResult(resumeAction);
        }

        protected Result Retry()
        {
            return new RetryResult();
        }        

        static ParsedExpression CreateNavigationResult<T>(Expression<Func<T, Result>> action) where T : Codeflow
        {
            var argumentExtractor = new ArgumentParser<T>();
            var result = argumentExtractor.Parse(action);
            return result;
        }

        static ParsedExpression CreateNavigationResult<T>(Expression<Func<T, Task<Result>>> action) where T : Codeflow
        {
            var argumentExtractor = new ArgumentParser<T>();
            var result = argumentExtractor.Parse(action);
            return result;
        }
    }
}
